package com.example.shutdown_v1.controller;

import com.example.shutdown_v1.dto.SensorDataPacket;
import com.example.shutdown_v1.entity.Sensor;
import com.example.shutdown_v1.entity.SensorBaselineHistory;
import com.example.shutdown_v1.entity.SensorData;
import com.example.shutdown_v1.entity.SwitchStateRecord;
import com.example.shutdown_v1.repository.SensorBaselineHistoryRepository;
import com.example.shutdown_v1.repository.SensorDataRepository;
import com.example.shutdown_v1.repository.SensorRepository;
import com.example.shutdown_v1.repository.SwitchStateRecordRepository;
import com.example.shutdown_v1.service.RedisSensorDataService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 传感器管理API
 */
@Slf4j
@RestController
@RequestMapping("/api/sensor")
@RequiredArgsConstructor
public class SensorController {

    private final SensorRepository sensorRepository;
    private final SensorDataRepository sensorDataRepository;
    private final SwitchStateRecordRepository stateRecordRepository;
    private final SensorBaselineHistoryRepository historyRepository;
    
    // 【新增】注入Redis服务（可选）
    @Autowired(required = false)
    private RedisSensorDataService redisSensorDataService;
    
    @Value("${data.storage.redis.enabled:false}")
    private boolean redisEnabled;

    /**
     * 注册新传感器
     * POST /api/sensor/register
     */
    @PostMapping("/register")
    public ResponseEntity<Map<String, Object>> registerSensor(@RequestBody SensorRequest request) {
        Map<String, Object> response = new HashMap<>();
        
        try {
            // 检查传感器是否已存在
            if (sensorRepository.findBySensorId(request.getSensorId()).isPresent()) {
                response.put("success", false);
                response.put("message", "传感器ID已存在");
                return ResponseEntity.badRequest().body(response);
            }
            
            Sensor sensor = new Sensor();
            sensor.setSensorId(request.getSensorId());
            sensor.setShopId(request.getShopId());
            sensor.setInstallPosition(request.getInstallPosition());
            sensor.setInstallPositionName(request.getInstallPositionName());
            sensor.setInstallDate(LocalDate.now());
            sensor.setStatus(1);
            
            sensorRepository.save(sensor);
            
            response.put("success", true);
            response.put("message", "传感器注册成功");
            response.put("sensor", sensor);
            
            log.info("[传感器] 注册成功: {}", request.getSensorId());
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("传感器注册失败", e);
            response.put("success", false);
            response.put("message", "注册失败: " + e.getMessage());
            return ResponseEntity.badRequest().body(response);
        }
    }

    /**
     * 查询传感器列表（包含最新状态）
     * GET /api/sensor/list?shopId={shopId}
     */
    @GetMapping("/list")
    public ResponseEntity<Map<String, Object>> listSensors(
            @RequestParam(required = false) Long shopId) {
        
        List<Sensor> sensors;
        if (shopId != null) {
            sensors = sensorRepository.findByShopId(shopId);
        } else {
            sensors = sensorRepository.findAll();
        }
        
        // 为每个传感器添加最新状态
        List<Map<String, Object>> sensorsWithState = sensors.stream().map(sensor -> {
            Map<String, Object> sensorMap = new HashMap<>();
            sensorMap.put("id", sensor.getId());
            sensorMap.put("sensorId", sensor.getSensorId());
            sensorMap.put("shopId", sensor.getShopId());
            sensorMap.put("installPosition", sensor.getInstallPosition());
            sensorMap.put("installPositionName", sensor.getInstallPositionName());
            sensorMap.put("installDate", sensor.getInstallDate());
            sensorMap.put("lastOnlineTime", sensor.getLastOnlineTime());
            sensorMap.put("isOffline", sensor.getIsOffline());
            sensorMap.put("sensorModel", sensor.getSensorModel());
            sensorMap.put("createdAt", sensor.getCreatedAt());
            sensorMap.put("updatedAt", sensor.getUpdatedAt());
            
            // 查询最新状态
            Optional<SwitchStateRecord> latestState = 
                    stateRecordRepository.findFirstBySensorIdOrderByRecordTimeDesc(sensor.getSensorId());
            sensorMap.put("status", latestState.map(SwitchStateRecord::getCurrentState).orElse("unknown"));
            sensorMap.put("lastStateChangeTime", latestState.map(SwitchStateRecord::getRecordTime).orElse(null));
            
            return sensorMap;
        }).toList();
        
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("sensors", sensorsWithState);
        response.put("count", sensorsWithState.size());
        
        return ResponseEntity.ok(response);
    }

    /**
     * 查询传感器详情
     * GET /api/sensor/detail/{sensorId}
     */
    @GetMapping("/detail/{sensorId}")
    public ResponseEntity<Map<String, Object>> getSensorDetail(@PathVariable String sensorId) {
        Optional<Sensor> sensorOpt = sensorRepository.findBySensorId(sensorId);
        
        if (sensorOpt.isEmpty()) {
            Map<String, Object> error = new HashMap<>();
            error.put("success", false);
            error.put("message", "传感器不存在");
            return ResponseEntity.notFound().build();
        }
        
        Sensor sensor = sensorOpt.get();
        
        // 获取最新状态
        Optional<SwitchStateRecord> latestState = 
                stateRecordRepository.findFirstBySensorIdOrderByRecordTimeDesc(sensorId);
        
        // 获取最近10条数据
        List<SensorData> recentData = sensorDataRepository
                .findTop10BySensorIdOrderByReceiveTimeDesc(sensorId);
        
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("sensor", sensor);
        response.put("currentState", latestState.map(SwitchStateRecord::getCurrentState).orElse("unknown"));
        response.put("recentData", recentData);
        
        return ResponseEntity.ok(response);
    }

    /**
     * 查询传感器历史数据（优先从Redis查询）
     * GET /api/sensor/data/{sensorId}?limit=100
     */
    @GetMapping("/data/{sensorId}")
    public ResponseEntity<Map<String, Object>> getSensorData(
            @PathVariable String sensorId,
            @RequestParam(defaultValue = "100") int limit) {
        
        Map<String, Object> response = new HashMap<>();
        response.put("success", true);
        response.put("sensorId", sensorId);
        
        // 优先从Redis查询（3小时热数据）
        if (redisEnabled && redisSensorDataService != null) {
            try {
                var redisData = redisSensorDataService.getLatestData(sensorId, limit);
                if (!redisData.isEmpty()) {
                    response.put("source", "redis");
                    response.put("data", redisData);
                    response.put("count", redisData.size());
                    response.put("ttl", "3小时");
                    return ResponseEntity.ok(response);
                }
            } catch (Exception e) {
                log.warn("[Redis] 查询失败，降级到MySQL: {}", sensorId, e);
            }
        }
        
        // 降级到MySQL查询
        PageRequest pageRequest = PageRequest.of(0, limit, Sort.by(Sort.Direction.DESC, "receiveTime"));
        List<SensorData> dataList = sensorDataRepository.findBySensorId(sensorId, pageRequest).getContent();
        
        response.put("source", "mysql");
        response.put("data", dataList);
        response.put("count", dataList.size());
        
        return ResponseEntity.ok(response);
    }
    
    /**
     * 查询传感器实时数据（最新一条，仅Redis）
     * GET /api/sensor/realtime/{sensorId}
     */
    @GetMapping("/realtime/{sensorId}")
    public ResponseEntity<Map<String, Object>> getRealtimeData(@PathVariable String sensorId) {
        Map<String, Object> response = new HashMap<>();
        
        if (!redisEnabled || redisSensorDataService == null) {
            response.put("success", false);
            response.put("message", "Redis未启用，无法查询实时数据");
            return ResponseEntity.badRequest().body(response);
        }
        
        try {
            var currentData = redisSensorDataService.getCurrentData(sensorId);
            if (currentData == null) {
                response.put("success", false);
                response.put("message", "未找到实时数据（可能传感器离线超过3小时）");
                return ResponseEntity.notFound().build();
            }
            
            response.put("success", true);
            response.put("source", "redis");
            response.put("data", currentData);
            return ResponseEntity.ok(response);
            
        } catch (Exception e) {
            log.error("[Redis] 查询实时数据失败: {}", sensorId, e);
            response.put("success", false);
            response.put("message", "查询失败: " + e.getMessage());
            return ResponseEntity.internalServerError().body(response);
        }
    }

    /**
     * 设置传感器当前状态为关闭基准值
     * POST /api/sensor/{sensorId}/set-closed
     */
    @PostMapping("/{sensorId}/set-closed")
    @CrossOrigin(originPatterns = "*", allowCredentials = "false")
    public ResponseEntity<?> setClosedBaseline(@PathVariable String sensorId) {
        try {
            // 1. 查找传感器
            Optional<Sensor> sensorOpt = sensorRepository.findBySensorId(sensorId);
            if (!sensorOpt.isPresent()) {
                return ResponseEntity.ok(Map.of(
                    "success", false,
                    "message", "传感器不存在: " + sensorId
                ));
            }
            
            Sensor sensor = sensorOpt.get();
            
            // 2. 从Redis获取当前实时数据
            if (!redisEnabled || redisSensorDataService == null) {
                return ResponseEntity.ok(Map.of(
                    "success", false,
                    "message", "Redis未启用，无法获取实时数据"
                ));
            }
            
            // 使用小写传感器ID查询Redis（修复大小写不匹配问题）
            String sensorIdLowerCase = sensorId.toLowerCase();
            Map<String, Object> currentData = redisSensorDataService.getSensorStatus(sensorIdLowerCase);
            if (currentData == null || currentData.isEmpty()) {
                log.warn("[{}] 无法从Redis获取实时数据: currentData={}", sensorId, currentData);
                return ResponseEntity.ok(Map.of(
                    "success", false,
                    "message", "无法获取传感器实时数据，请确保传感器在线并且有数据上报"
                ));
            }
            
            log.info("[{}] 从Redis获取到的数据: {}", sensorId, currentData);
            
            // 3. 设置IM600关闭基准值（系统统一使用IM600传感器）
            boolean updated = false;
            
            Double currentRoll = (Double) currentData.get("roll");
            Double currentPitch = (Double) currentData.get("pitch");
            Double currentYaw = (Double) currentData.get("yaw");
            Double accelZ = (Double) currentData.get("accelZ");
            
            // 获取圈数数据（如果有）
            Double rollTurnCount = (Double) currentData.get("rollTurnCount");
            Double yawTurnCount = (Double) currentData.get("yawTurnCount");
            
            log.info("[{}] 准备设置基准值 - Roll:{}, Pitch:{}, Yaw:{}, AccelZ:{}, 圈数[R:{}, Y:{}]", 
                    sensorId, currentRoll, currentPitch, currentYaw, accelZ, rollTurnCount, yawTurnCount);
            
            if (currentRoll != null && currentPitch != null && currentYaw != null && accelZ != null) {
                // 保存欧拉角基准值
                sensor.setRollBaselineClosed(currentRoll);
                sensor.setPitchBaselineClosed(currentPitch);
                sensor.setYawBaselineClosed(currentYaw);
                
                // 保存加速度 Z 轴基准值（垂直移动时作为辅助验证）
                sensor.setAccelBaselineZ(accelZ);
                
                // 保存圈数基准值（如果有的话）
                if (rollTurnCount != null && yawTurnCount != null) {
                    sensor.setRollTurnBaselineClosed(rollTurnCount);
                    sensor.setYawTurnBaselineClosed(yawTurnCount);
                    log.info("[{}] 圈数基准值已保存 - Roll:{:.3f}, Yaw:{:.3f}", 
                            sensorId, rollTurnCount, yawTurnCount);
                }
                
                sensor.setBaselineUpdateTime(LocalDateTime.now());
                updated = true;
                
                // 记录手动校准历史
                SensorBaselineHistory history = SensorBaselineHistory.builder()
                        .sensorId(sensorId)
                        .sensorModel("IM600")
                        .accelBaselineX(null)
                        .accelBaselineY(null)
                        .accelBaselineZ(accelZ)
                        .rollBaselineClosed(currentRoll)
                        .pitchBaselineClosed(currentPitch)
                        .yawBaselineClosed(currentYaw)
                        .createdAt(LocalDateTime.now())
                        .calibrationType("manual")
                        .baselineAgeDays(null)
                        .build();
                historyRepository.save(history);
                
                log.info("[{}] 设置关闭基准值成功 - Euler: Roll={:.2f}°, Pitch={:.2f}°, Yaw={:.2f}°, AccelZ={:.3f}m/s²", 
                        sensorId, currentRoll, currentPitch, currentYaw, accelZ);
            } else {
                log.error("[{}] 数据不完整,无法设置基准值", sensorId);
                return ResponseEntity.ok(Map.of(
                    "success", false,
                    "message", "传感器数据不完整: Roll=" + currentRoll + 
                              ", Pitch=" + currentPitch + ", Yaw=" + currentYaw + ", AccelZ=" + accelZ
                ));
            }
            
            // 4. 保存到数据库
            if (updated) {
                sensorRepository.save(sensor);
                
                // 5. 重新计算状态并更新Redis（🔥 关键修复：不强制设置为closed，让算法自动计算）
                if (redisEnabled && redisSensorDataService != null) {
                    try {
                        // 创建当前数据包用于状态识别
                        SensorDataPacket currentPacket = new SensorDataPacket();
                        currentPacket.setMac(sensorId);
                        currentPacket.setRoll(currentRoll);
                        currentPacket.setPitch(currentPitch);
                        currentPacket.setYaw(currentYaw);
                        currentPacket.setAccelZ(accelZ);
                        if (rollTurnCount != null) currentPacket.setRollTurnCount(rollTurnCount);
                        if (yawTurnCount != null) currentPacket.setYawTurnCount(yawTurnCount);
                        
                        // 需要注入状态识别服务
                        // 暂时使用简化逻辑：设置基准值后，当前数据与基准值的差为0，应该识别为closed
                        // TODO: 注入ValveStateRecognitionService进行完整识别
                        redisSensorDataService.saveSensorStatus(
                            sensorIdLowerCase,
                            "closed",           // 基准值设置后，理论上应该为closed（因为差值为0）
                            0.0,               // 与基准值的距离为0
                            1.0,               // 置信度100%
                            currentPacket
                        );
                        
                        log.info("[{}] 基准值设置后更新Redis状态 (差值=0, 应为closed)", sensorId);
                    } catch (Exception e) {
                        log.warn("[{}] 更新Redis状态失败: {}", sensorId, e.getMessage());
                    }
                }
                
                return ResponseEntity.ok(Map.of(
                    "success", true,
                    "message", "关闭基准值设置成功，状态已更新",
                    "sensorId", sensorId,
                    "sensorModel", "IM600",
                    "baselineUpdateTime", sensor.getBaselineUpdateTime(),
                    "currentState", "closed"
                ));
            } else {
                return ResponseEntity.ok(Map.of(
                    "success", false,
                    "message", "无法从当前数据中获取有效角度值"
                ));
            }
            
        } catch (Exception e) {
            log.error("[{}] 设置关闭基准值失败", sensorId, e);
            return ResponseEntity.ok(Map.of(
                "success", false,
                "message", "设置失败: " + e.getMessage()
            ));
        }
    }

    /**
     * 更新传感器配置
     * @param sensorId 传感器ID
     * @param config 配置信息
     * @return 响应结果
     */
    @PutMapping("/{sensorId}/config")
    public ResponseEntity<Map<String, Object>> updateSensorConfig(
            @PathVariable String sensorId,
            @RequestBody Map<String, Object> config) {
        try {
            Optional<Sensor> sensorOpt = sensorRepository.findBySensorId(sensorId);
            if (!sensorOpt.isPresent()) {
                return ResponseEntity.badRequest().body(Map.of(
                    "success", false,
                    "message", "传感器不存在"
                ));
            }
            
            Sensor sensor = sensorOpt.get();
            
            // 更新多圈检测配置
            if (config.containsKey("useMultiTurnDetection")) {
                Integer useMultiTurn = (Integer) config.get("useMultiTurnDetection");
                sensor.setUseMultiTurnDetection(useMultiTurn);
            }
            
            // 更新安装方向
            if (config.containsKey("installDirection")) {
                Integer installDirection = (Integer) config.get("installDirection");
                sensor.setInstallDirection(installDirection);
            }
            
            sensorRepository.save(sensor);
            
            log.info("传感器 {} 配置更新成功", sensorId);
            return ResponseEntity.ok(Map.of(
                "success", true,
                "message", "配置更新成功"
            ));
            
        } catch (Exception e) {
            log.error("更新传感器配置失败: {}", e.getMessage(), e);
            return ResponseEntity.badRequest().body(Map.of(
                "success", false,
                "message", "配置更新失败: " + e.getMessage()
            ));
        }
    }

    /**
     * 请求体：传感器注册
     */
    @lombok.Data
    public static class SensorRequest {
        private String sensorId;
        private Long shopId;
        private String installPosition; // electric_switch/water_valve/gas_valve
        private String installPositionName; // 水阀门/气阀门/电闸开关等
    }
}

